package com.atguigu.tingshu.common.login;

import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class GuiGuLoginAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Around("execution(* com.atguigu.tingshu.*.api.*.*(..)) && @annotation(guiGuLogin)")
    public Object login(ProceedingJoinPoint joinPoint,GuiGuLogin guiGuLogin) throws Throwable{
        // 0. 获取请求对象,RequestContextHolder上下文对象获取ServletRequestAttributes对象
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = attributes.getRequest();

        // 1. 从请求头获取token(前端传递过来的)
        String token = request.getHeader("token");
        // 2. 从token查询redis(redis的key就是token)
        // 可以查询到是登录，查询不到，不是登录
        // 因为GuiguLogin注解有属性。required==true表示必须登录
        // required==false表示可以登录可以不登陆
        boolean isRequired = guiGuLogin.required();
        if(isRequired){ // 表示必须登录
            if(StringUtils.isEmpty(token)){
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
            }
            // 如果token不为空，根据token查询redis，判断查询数据是否为空，如果为空，返回登陆提示信息
            UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(token);
            // 如果为空返回登陆提示信息
            if(userInfo == null){
                throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
            }

        }

        if (!StringUtils.isEmpty(token)){
            // 组成缓存key
            String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
            // 获取缓存中用户数据
            UserInfo userInfo = (UserInfo) this.redisTemplate.opsForValue().get(loginKey);
            // 如果为空返回登陆提示信息
            if(userInfo != null){
                // 存储用户id
                AuthContextHolder.setUserId(userInfo.getId());
            }
        }
        Object obj = joinPoint.proceed();
        return obj;
    }



}
